// Copyright 2007 Google Inc.
// All Rights Reserved.

package com.google.jessewilson.codesearch.gtagssearch;

import java.io.File;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;

/**
 * Defines a typesafe set of known gtags file types, as well as helper methods
 * to convert from typical java objects to these file types.
 *
 * @author Ted Mao (tmao@google.com)
 */
enum GtagsLanguageType {
  C("c++", new HashSet<String>(Arrays.asList("c", "cc", "cpp", "h", "hpp"))),
  JAVA("java", new HashSet<String>(Arrays.asList("java"))),
  PYTHON("python", new HashSet<String>(Arrays.asList("py")));

  /**
   * Language type string understood by the gtags executable
   */
  private final String languageType;

  /**
   * Set of file extensions to map to this language type
   */
  final Set<String> fileExtensions;

  /**
   * Mapping from file extension to language type
   */
  private static HashMap<String, GtagsLanguageType> extensionToLanguageMap;

  GtagsLanguageType(String languageType, Set<String> fileExtensions) {
    this.languageType = languageType;
    this.fileExtensions = fileExtensions;
  }

  public String getLanguageType() {
    return languageType;
  }

  /**
   * Returns the gtags language type for the given file's file extension,
   * or null if no language type is associated with the file's file extension.
   *
   * @param file the file
   * @return the gtags language type for the given file's file extension,
   *   or null if no language type is associated with the file's file extension.
   */
  public static GtagsLanguageType ofFile(File file) {
    String filename = file.getName();
    int indexOfLastDot = filename.lastIndexOf(".");
    if (indexOfLastDot != -1) {
      return ofFileExtension(filename.substring(indexOfLastDot+1));
    } else {
      return null;
    }
  }

  /**
   * Returns the gtags language type associated with the given file extension,
   * or null if no language type is associated with the given file extension.
   *
   * @param extension the file extension
   * @return the gtags language type associated with the given file extension,
   *   or null if no language type is associated with the given file extension.
   */
  public static GtagsLanguageType ofFileExtension(String extension) {
    if (extensionToLanguageMap == null) {
      extensionToLanguageMap = new HashMap<String, GtagsLanguageType>();
      for (GtagsLanguageType languageType : GtagsLanguageType.values()) {
        for (String fileExtension : languageType.fileExtensions) {
          extensionToLanguageMap.put(fileExtension, languageType);
        }
      }
    }
    return extensionToLanguageMap.get(extension);
  }

}
